home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 365_02 / move5.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  5KB  |  257 lines

  1. /* move5.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  8.  */
  9.  
  10.  
  11. /* This file contains the word-oriented movement functions */
  12.  
  13. #include "config.h"
  14. #include "ctype.h"
  15. #include "vi.h"
  16.  
  17. MARK    m_fword(m, cnt, cmd, prevkey)
  18.     MARK    m;    /* movement is relative to this mark */
  19.     long    cnt;    /* a numeric argument */
  20.     int    cmd;    /* either 'w' or 'W' */
  21.     int    prevkey;/* previous command... if 'c' then exclude whitespace */
  22. {
  23.     REG long    l;
  24.     REG char    *text;
  25.     REG int        i;
  26.  
  27.     DEFAULT(1);
  28.  
  29.     l = markline(m);
  30.     pfetch(l);
  31.     text = ptext + markidx(m);
  32.  
  33. #ifndef CRUNCH
  34.     /* As a special case, "cw" or "cW" on whitespace without a count
  35.      * treats the single whitespace character under the cursor as a word.
  36.      */
  37.     if (cnt == 1L && prevkey == 'c' && isspace(*text))
  38.     {
  39.         return m + 1L;
  40.     }
  41. #endif
  42.  
  43.     while (cnt-- > 0) /* yes, ASSIGNMENT! */
  44.     {
  45.         i = *text++;
  46.  
  47.         if (cmd == 'W')
  48.         {
  49.             /* include any non-whitespace */
  50.             while (i && !isspace(i))
  51.             {
  52.                 i = *text++;
  53.             }
  54.         }
  55.         else if (isalnum(i) || i == '_')
  56.         {
  57.             /* include an alphanumeric word */
  58.             while (i && isalnum(i))
  59.             {
  60.                 i = *text++;
  61.             }
  62.         }
  63.         else
  64.         {
  65.             /* include contiguous punctuation */
  66.             while (i && !isalnum(i) && !isspace(i))
  67.             {
  68.                 i = *text++;
  69.             }
  70.         }
  71.  
  72.         /* if not part of "cw" or "cW" command... */
  73.         if (prevkey != 'c' || cnt > 0)
  74.         {
  75.             /* include trailing whitespace */
  76.             while (!i || isspace(i))
  77.             {
  78.                 /* did we hit the end of this line? */
  79.                 if (!i)
  80.                 {
  81.                     /* "dw" shouldn't delete newline after word */
  82.                     if (prevkey && cnt == 0)
  83.                     {
  84.                         break;
  85.                     }
  86.  
  87.                     /* move to next line, if there is one */
  88.                     l++;
  89.                     if (l > nlines)
  90.                     {
  91.                         return MARK_UNSET;
  92.                     }
  93.                     pfetch(l);
  94.                     text = ptext;
  95.                 }
  96.  
  97.                 i = *text++;
  98.             }
  99.         }
  100.         text--;
  101.     }
  102.  
  103.     /* if argument to operator, then back off 1 char since "w" and "W"
  104.      * include the last char in the affected text.
  105.      */
  106.     if (prevkey)
  107.     {
  108.         text--;
  109.     }
  110.  
  111.     /* construct a MARK for this place */
  112.     m = buildmark(text);
  113.     return m;
  114. }
  115.  
  116.  
  117. MARK    m_bword(m, cnt, cmd)
  118.     MARK    m;    /* movement is relative to this mark */
  119.     long    cnt;    /* a numeric argument */
  120.     int    cmd;    /* either 'b' or 'B' */
  121. {
  122.     REG long    l;
  123.     REG char    *text;
  124.  
  125.     DEFAULT(1);
  126.  
  127.     l = markline(m);
  128.     pfetch(l);
  129.     text = ptext + markidx(m);
  130.     while (cnt-- > 0) /* yes, ASSIGNMENT! */
  131.     {
  132.         text--;
  133.  
  134.         /* include preceding whitespace */
  135.         while (text < ptext || isspace(*text))
  136.         {
  137.             /* did we hit the end of this line? */
  138.             if (text < ptext)
  139.             {
  140.                 /* move to preceding line, if there is one */
  141.                 l--;
  142.                 if (l <= 0)
  143.                 {
  144.                     return MARK_UNSET;
  145.                 }
  146.                 pfetch(l);
  147.                 text = ptext + plen - 1;
  148.             }
  149.             else
  150.             {
  151.                 text--;
  152.             }
  153.         }
  154.  
  155.         if (cmd == 'B')
  156.         {
  157.             /* include any non-whitespace */
  158.             while (text >= ptext && !isspace(*text))
  159.             {
  160.                 text--;
  161.             }
  162.         }
  163.         else if (isalnum(*text) || *text == '_')
  164.         {
  165.             /* include an alphanumeric word */
  166.             while (text >= ptext && isalnum(*text))
  167.             {
  168.                 text--;
  169.             }
  170.         }
  171.         else
  172.         {
  173.             /* include contiguous punctuation */
  174.             while (text >= ptext && !isalnum(*text) && !isspace(*text))
  175.             {
  176.                 text--;
  177.             }
  178.         }
  179.         text++;
  180.     }
  181.  
  182.     /* construct a MARK for this place */
  183.     m = buildmark(text);
  184.     return m;
  185. }
  186.  
  187. MARK    m_eword(m, cnt, cmd)
  188.     MARK    m;    /* movement is relative to this mark */
  189.     long    cnt;    /* a numeric argument */
  190.     int    cmd;    /* either 'e' or 'E' */
  191. {
  192.     REG long    l;
  193.     REG char    *text;
  194.     REG int        i;
  195.  
  196.     DEFAULT(1);
  197.  
  198.     l = markline(m);
  199.     pfetch(l);
  200.     text = ptext + markidx(m);
  201.     while (cnt-- > 0) /* yes, ASSIGNMENT! */
  202.     {
  203.         if (*text)
  204.             text++;
  205.         i = *text++;
  206.  
  207.         /* include preceding whitespace */
  208.         while (!i || isspace(i))
  209.         {
  210.             /* did we hit the end of this line? */
  211.             if (!i)
  212.             {
  213.                 /* move to next line, if there is one */
  214.                 l++;
  215.                 if (l > nlines)
  216.                 {
  217.                     return MARK_UNSET;
  218.                 }
  219.                 pfetch(l);
  220.                 text = ptext;
  221.             }
  222.  
  223.             i = *text++;
  224.         }
  225.  
  226.         if (cmd == 'E')
  227.         {
  228.             /* include any non-whitespace */
  229.             while (i && !isspace(i))
  230.             {
  231.                 i = *text++;
  232.             }
  233.         }
  234.         else if (isalnum(i) || i == '_')
  235.         {
  236.             /* include an alphanumeric word */
  237.             while (i && isalnum(i))
  238.             {
  239.                 i = *text++;
  240.             }
  241.         }
  242.         else
  243.         {
  244.             /* include contiguous punctuation */
  245.             while (i && !isalnum(i) && !isspace(i))
  246.             {
  247.                 i = *text++;
  248.             }
  249.         }
  250.         text -= 2;
  251.     }
  252.  
  253.     /* construct a MARK for this place */
  254.     m = buildmark(text);
  255.     return m;
  256. }
  257.